/**
 * @file easy_fsmc.h
 * @author your name (you@domain.com)
 * @brief fsmc
 * @version 0.1
 * @date 2023-08-06
 * 
 * @copyright Copyright (c) 2023
 * 
 */

#ifndef EASY_FSMC_H
#define EASY_FSMC_H

/******************************* Includes ********************************/
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C"
{
#endif

/******************************* Macros ******************************/
#define FSMC_E(...)  printf(__VA_ARGS__)
#define FSMC_I(...)  printf(__VA_ARGS__)
#define FSMC_D(...)  printf(__VA_ARGS__)
 
/******************************* Typedef ******************************/
typedef int FSMC_EVENT;
typedef int FSMC_STATE;
typedef void (*action_callback)(FSMC_EVENT event, void *usrdata);

typedef struct fsm_status
{
    FSMC_EVENT event;                                   /* Event*/
    FSMC_STATE cur_sta;                                 /* Cur state */
    action_callback event_action;                       /* Action func */
    FSMC_STATE next_sta;                                /* Next  state*/
    void *usrdata;                                      /* Usr data*/
}fsm_status_t;


typedef struct fsm_handle
{
    fsm_status_t    *fsmtb;      /* Fsm table */
    FSMC_STATE       cur_sta;    /* Cur state */
    FSMC_EVENT       cur_event;      /* Cur event */
    uint8_t          sta_max_n;  /* Fsm table count */
}fsm_handle_t;


/******************************* Variables ******************************/

/******************************* Functions ******************************/

/**
 * @brief init fsm handle
 * 
 * @param fsmtb fsm table
 * @param init_event init event
 * @param init_state init state
 * @param count      fsm table count   
 * @return fsm_handle_t* NULL is error
 */
fsm_handle_t *easy_fsm_init(fsm_status_t  *fsmtb, FSMC_EVENT init_event, FSMC_STATE init_state, int count);

/**
 * @brief process fsm states, need loop call
 * detect states that are the same as the current state and event, if same call event_action
 * @param handle fsm_handle_t *
 * @return int 0
 */
int easy_fsm_process(fsm_handle_t *handle);

/**
 * @brief set cur event
 * 
 * @return int 0
 */
int easy_fsm_event_set(fsm_handle_t *handle, FSMC_EVENT event);

/**
 * @brief free fsm handle
 * 
 * @return int 0
 */
int easy_fsm_deinit(fsm_handle_t *handle);

#ifdef __cplusplus
}
#endif

#endif
/******************************* End of file ******************************/